home *** CD-ROM | disk | FTP | other *** search
- *** Adding Z Buffer output to Rayshade 4.0 ***
-
- Mark Maimone, mwm@cs.cmu.edu (BITNET: mwm%cs.cmu.edu@CARNEGIE)
-
- 18 March 1992
-
- I've made a preliminary attempt at getting Rayshade to output depth
- information in addition to rendered images. I need this information since I
- want to use Rayshade to generate test images for a stereo algorithm. Having
- the "true" depth means I can test how accurately my stereo algorithm
- reconstructs it (depth) from only the stereo pair of 2D images without
- knowing the inherent 3D structure.
-
- My technique is quite basic. I rely on the anti-aliasing scheme to
- sample the pixels, and remember the distance from the Eye to the nearest
- object along each generated ray. Of all these distances associated with a
- pixel, I arbitrarily choose the one nearest to the eye to denote the "true"
- distance.
-
- This scheme has several problems (and I'm sure others will find
- more). It doesn't return the distance of the object that occupies *most* of
- the pixel, it merely returns the distance of the object it finds nearest to
- the eye; it doesn't matter if it only occupies 5% of the pixel. It lets the
- antialiasing scheme choose which rays are relevant; a bad antialiasing
- scheme may well yield a bad Z buffer. It treats transparent objects as
- opaque (changing this *should* only require adding a very simple test in
- trace_pixel(), but I don't know enough about the internals yet). It assumes
- all distances are positive (this, at least, should be a reasonable
- assumption).
-
- The changes were realized entirely within the
- "rayshade-4.0/rayshade" directory. No changes were made to the libraries.
- Adding the Z buffer to rayshade involves several small changes to files in
- that directory, plus the addition of two more (short) source files, zbuf.c
- and zbuf.h.
-
- ======== COMMAND LINE INTERFACE
-
- Very easy. Just run rayshade with the "-z filename" option to write
- the Z buffer to the named file. You must name some file, it won't write to
- stdout.
-
- ======== IMPLEMENTATION
-
- Rayshade-4.0 already computes everything needed to generate the Z
- buffer, but it throws the information away. I've added an external Float
- array (zbuffer in zbuf.c) to store the distance to the nearest object in
- each pixel. You must have enough memory available for a Float array with
- the same dimensions as the window being rendered.
-
- I put a hook into the routine where Rayshade finds the "first"
- object hit by a given ray (trace_pixel() in rayshade/raytrace.c). That hook
- calls ZbufAdd() to store the current distance in global array zbuffer.
- ZbufAdd() maps the Float index values to ints by using floor(pix+0.5) for
- both X and Y.
-
- ======== FILE FORMAT
-
- The first few lines in the file are comments describing the source
- of the data. After that, the depth information follows, with each line
- representing a single pixel:
-
- <int x-coord> <int y-coord> <Float distance>
-
- A distance of -1 means the pixel denotes background. The file is ordered by
- scanline, with a blank line separating scanlines. This format is ideally
- suited for viewing the depth map using GNUplot (see comments in zbuf.c).
-
- Here's a sample output file:
-
- # Depth Map for Rayshade output file
- # Input RAY file: "../Examples/planet.ray"
- # Resolution for this rendering is 50x50
- # window from (0,0) to (49,49)
- # Index 0: 11412 hits
- 0 0 -1
- 0 1 -1
- 0 2 -1
- 0 3 -1
- . [ I deleted many lines for brevity ]
- .
- 12 13 -1
- 12 14 -1
- 12 15 -1
- 12 16 3.75485
- 12 17 3.60294
- 12 18 3.52262
- 12 19 3.46714
- 12 20 3.42647
- 12 21 3.40308
-
- ======== COMMENTS
-
- Please post any comments to the rayshade-users@cs.princeton.edu
- mailing list, or if you prefer you may send them directly to me at
- mwm@cs.cmu.edu. Any comments are welcome, especially ones of the form "your
- scheme for computing the Z buffer is useless because...."
-
- Mark Maimone
- CMU Computer Science
- mwm@cs.cmu.edu
-
-
- ======== EXAMPLES
-
- % rayshade -R 50 50 -z zbuf.dat Examples/balls.ray > balls.rle
- % gnuplot
- gnuplot> set term x11 [or whatever you're on]
- gnuplot> set sample 2500 [for a 50x50 image]
- gnuplot> set parametric [needed to plot 3D data]
- gnuplot> splot 'zbuf.dat' with lines
- [gives a nice height map grid]
- gnuplot> help set view [info on changing viewpoint]
- gnuplot> set view 45, 45 [a sample viewpoint]
- gnuplot> quit
-
- Warning! Distances are expected to always be positive, so background
- pixels are represented by a distance of ZBUF_INF (i.e., -1). To get
- nice looking GNUplot output you should replace all -1's with the maximum
- distance. On UNIX:
-
- % rayshade -R 50 50 -z zbuf.dat Examples/planet.ray > balls.rle
- % awk 'BEGIN {max = -1} NF == 3 { if ($3 > max) max = $d} END \
- {print max}' < zbuf.dat [this gives you the max]
- 3.69359
- % sed s/-1/3.69359/g < zbuf.dat | awk 'NF == 3 { print $1" "$2" -"$3 \
- ; next} {print}' > zbuf.plot [replace -1 with max, make all
- distances negative so the
- plot appears rightside up]
- % gnuplot
- .
- .
- gnuplot> set zrange [-3.7:0]
- gnuplot> splot 'zbuf.plot'
-